/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/
/* tcpdemux.c - tcpdemux */

#include "tcbtab.h"
#include "tcpfms.h"
#include "tcb.h"

/*------------------------------------------------------------------------
 *  tcpdemux -  do TCP port demultiplexing
 *------------------------------------------------------------------------
 */
//verificar
struct tcb * tcpdemux(struct udp *pudp)
{
    
  //	struct	ip	*pip = (struct ip *)pep->ep_data;
        struct	tcp	*ptcp = (struct tcp*)(pudp->udp_data);
  //	struct	tcb	*ptcb;
	int		tcbn, lstcbn;


	sem_wait(&(tcps_tmutex));
	for (tcbn=0, lstcbn = -1; tcbn<NTCP; ++tcbn) {
            if (tcbtab[tcbn]->tcb_state == TCPS_FREE)
                    continue;
            if (ptcp->tcp_dport == tcbtab[tcbn]->tcb_lport &&
                ptcp->tcp_sport == tcbtab[tcbn]->tcb_rport
                && pudp->ip_src == tcbtab[tcbn]->tcb_rip &&
                pudp->ip_dst == tcbtab[tcbn]->tcb_lip) {
                    break;
            }
            if (tcbtab[tcbn]->tcb_state == TCPS_LISTEN &&
                ptcp->tcp_dport == tcbtab[tcbn]->tcb_lport)
                    lstcbn = tcbn;
	}
	if (tcbn >= NTCP)
        {
            if (ptcp->tcp_code & TCPF_SYN)
                tcbn =  lstcbn;
            else
                tcbn = -1;
        }
        sem_post(&(tcps_tmutex));
	if (tcbn < 0)
            return 0;
	
        sem_wait(&(tcbtab[tcbn]->tcb_mutex));
	if (tcbtab[tcbn]->tcb_state == TCPS_FREE)
            return 0;			// OOPS! Lost it...
	return (struct tcb*)&tcbtab[tcbn];
}